package com.xish.api.activity;

import com.xish.api.GeoLocation;
import com.xish.api.activity.search.ActivitySearchCondition;
import com.xish.api.activity.search.query.*;
import com.xish.api.follow.FollowService;
import com.xish.api.genre.GenreService;
import com.xish.api.operating.OperatingCondition;
import com.xish.api.operating.OperatingService;
import com.xish.api.poi.PoiService;
import com.xish.api.shop.ShopService;
import com.xish.api.trade.TradeService;
import com.xish.model.bean.*;
import com.xish.view.JsonConverter;
import com.xish.view.json.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static java.lang.Math.abs;
import static java.lang.Math.round;

@Service
public class ActivityService {

    private static final Logger LOG = LoggerFactory.getLogger(ActivityService.class);

    @Autowired
    private ActivityRepository activityRepository;

    @Autowired
    private JsonConverter jsonConverter;

    @Autowired
    private PoiService poiService;

    @Autowired
    private TradeService tradeService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private FollowService followService;

    @Autowired
    private GenreService genreService;

    @Autowired
    private OperatingService operatingService;

    public ActivitySearchResult search(ActivitySearchCondition condition) {
        List<Integer> list = new ArrayList<>();
        long activityCount = 0;

        if (!condition.hasSpecialCondition()) {
            List<Integer> first = activityRepository.searchIdListByQuery(new ActivityHighlightRuleOne(condition, list));
            if ((first != null) && !first.isEmpty()) {
                list.addAll(first);
                activityCount += first.size();
            }

            List<Integer> second = activityRepository.searchIdListByQuery(new ActivityHighlightRuleTwo(condition, list));
            if ((second != null) && !second.isEmpty()) {
                list.addAll(second);
                activityCount += second.size();
            }

            if (condition.hasGeoLocation()) {
                List<Integer> third = activityRepository.searchIdListByQuery(new ActivityHighlightRuleThree(condition, list));
                if ((third != null) && !third.isEmpty()) {
                    list.addAll(third);
                    activityCount += third.size();
                }
            }

            List<Integer> fourth = activityRepository.searchIdListByQuery(new ActivityHighlightRuleFour(condition, list));
            if ((fourth != null) && !fourth.isEmpty()) {
                list.addAll(fourth);
                activityCount += fourth.size();
            }
        }

        ActivityHighlightRuleCommon ruleCommon = new ActivityHighlightRuleCommon(condition, list);
        List<Integer> fifth = activityRepository.searchIdListByQuery(ruleCommon);
        if ((fifth != null) && !fifth.isEmpty()) {
            list.addAll(fifth);
        }

        ruleCommon.setLimitInQuery(false);
        activityCount += activityRepository.countByQuery(ruleCommon);

        List<Activity> activities = new ArrayList<>();
        if (!list.isEmpty()) {
            for (int index=0; index<list.size(); index++) {
                //json的格式输出
                activities.add(findActivityById(list.get(index), condition, index));
            }
        }
        LOG.debug("search list size: {}", activities.size());

        ActivitySearchResult searchResult = new ActivitySearchResult();
        searchResult.setList(activities);
        searchResult.setCount(activityCount);

        return searchResult;
    }

    public Activity findActivityById(int id) {
        return findActivityById(id, null, -1);
    }

    public Activity findActivityById(int id, ActivitySearchCondition condition, int activityIndex) {
        WzmActivity wzmActivity = activityRepository.findById(id);
        Activity activity = jsonConverter.convertWzmActivity(wzmActivity);

        if (activity != null) {
            int poiId = Integer.valueOf(wzmActivity.getPoiId());
            LOG.info("poiId = {}", poiId);

            if (poiId > 0) {
                WzmPoi wzmPoi = poiService.findById(poiId);
                if (wzmPoi != null) {
                    activity.setPoi(jsonConverter.convertWzmPoi(wzmPoi));
                } else {
                    activity.setPoi(new Poi(""));
                }

                WzmShop wzmShop = shopService.findByPoiId(poiId);
                if (wzmShop != null) {
                    Shop shop = new Shop();
                    shop.setId(wzmShop.getId());
                    shop.setTitle(wzmShop.getTitle());
                    shop.setIcon(jsonConverter.getShopImage(wzmShop.getPic(), 0));
                    shop.setSummary(wzmShop.getSummary());

                    activity.setShop(shop);
                }
            }

            if (condition != null) {
                //todo: user follow
                WzmActivityUserfollow userfollow = followService.findFollow(0, condition.getUuid());
                if (userfollow != null) {
                    activity.setIsFollow(1);
                }

                //距离的计算
                if (condition.hasGeoLocation()
                        && !wzmActivity.getLat().isEmpty()
                        && !wzmActivity.getLon().isEmpty()) {
                    GeoLocation userLocation = condition.getGeoLocation();
                    GeoLocation activityLocation = new GeoLocation(
                            Double.valueOf(wzmActivity.getLat()),
                            Double.valueOf(wzmActivity.getLon()));

                    long distance = round(abs(userLocation.distance(activityLocation)));
                    activity.setDistanceDescription(distance + "KM");
                }
            }

            activity.setGenreMainName("");
            activity.setGenreMainImage("");
            if (wzmActivity.getGenreMain() > 0) {
                WzmGenre genre = genreService.findById(wzmActivity.getGenreMain());
                if (genre != null) {
                    activity.setGenreMainName(genre.getName());

                    if (condition != null) {
                        activity.setGenreMainImage(jsonConverter.getGenreImage
                                (condition.getOs().toLowerCase().equals("android")
                                        ? genre.getIconNewAndroid()
                                        : genre.getIconNew()));
                    }
                }
            }

            activity.setBookStatus(1); //normal

            long currentTime = System.currentTimeMillis() / 1000L;
            boolean isActivityEnd = wzmActivity.getEndTime() > 0
                    && (Long.valueOf(wzmActivity.getEndTime()) <= currentTime);

            WzmActivityTrade trade = tradeService.findByActivityId(wzmActivity.getId());
            if (trade != null) {
                activity.setSoldOut(trade.getSoldOut() ? 1 : 0);
                activity.setBookEndTime(trade.getBookEndtime());
                activity.setBuyType(trade.getBuyType() ? 1 : 0);

                if (trade.getSoldOut()) {
                    activity.setBookStatus(3); //已抢光
                }

                if (isActivityEnd || wzmActivity.getStatus()) {
                    activity.setBookStatus(2); //已截止
                }

                Price price = new Price();
                price.setLow(trade.getLowestPrice());
                price.setHigh(trade.getMaxPrice());

                //运营位处理
                ArrayList<PriceDetail> priceDetails = new ArrayList<>();
                int operatingSort = operatingService.calculateOperatingSortByActivityIndex(activityIndex);
                if (operatingSort >= 0) {
                    OperatingCondition oc = new OperatingCondition();
                    oc.setSort(operatingSort);
                    oc.setStatus(1);
                    oc.setCurrentTime(System.currentTimeMillis() / 1000L);

                    if (condition != null) {
                        oc.setChannel(condition.getChannel());
                        oc.setPlatform(condition.getOs());
                        oc.setCityPoiId(String.valueOf(condition.getCityPoiId()));
                    }

                    List<Operating> operatingList = operatingService.findByCondition(oc);
                    if ((operatingList != null) && operatingList.size() > 0) {
                        //todo:运营位处理
                        for (Operating op : operatingList) {
                            priceDetails.add(new PriceDetail(op.getTitle(), "", ""));
                        }
                    }
                }
                price.setList(priceDetails);

                activity.setPrice(price);
            }

            if (activity.getBookStatus() == 1 && isActivityEnd) {
                activity.setBookStatus(4); //已结束
            }
        }

        //todo:JSON_VIEW的缓存处理,不是所有的字段都可以缓存
        return activity;
    }

}
